use crate::error::{Error, ErrorKind};
use rustc_serialize::hex::{FromHex, ToHex};
/// 大端法
pub fn int2bytes(value: i32) -> [u8; 4] {
    value.to_be_bytes()
}

/// int数组转换成u8数组  大端法
pub fn int_array_to_bytes(ints: &[i32]) -> Vec<u8> {
    let mut ret = vec![];
    for i in ints {
        let bytes = i.to_be_bytes();
        ret.extend_from_slice(&bytes);
    }
    ret
}

/// 二进制字符串转换为byte
pub fn binary_str_to_byte(binary_str: &str) -> Result<u8, Error> {
    let mut ret = 0u8;
    for (i, b) in binary_str.chars().rev().enumerate() {
        if b != '0' && b != '1' {
            return Err(Error::from_kind(ErrorKind::Msg(
                "binary_str2byte argument must be 0001111 or 111".to_string(),
            )));
        }
        let bv = b as u8 - b'0';
        ret += bv * 2u8.pow(i as u32);
    }
    Ok(ret)
}

/// u8转换成二进制的字符串
pub fn byte_to_binary_str(b: u8) -> String {
    format!("{:08b}", b)
}

/// bytes转换成二进制的字符串
pub fn bytes_to_binary_str(b: &[u8]) -> String {
    let mut ret = String::default();
    for bv in b {
        ret.push_str(&format!("{:08b}", bv));
    }
    ret
}
/// 2进制的字符串转换成bytes数组
pub fn binary_str_to_bytes(binary_str: &str) -> Result<Vec<u8>, Error> {
    let bytes = binary_str.as_bytes();
    let len = bytes.len();
    if len % 8 != 0 {
        return Err(ErrorKind::Msg(
            "binary_str_to_bytes: argument length must % 8 == 0".to_string(),
        )
        .into());
    }
    let chunk8 = bytes.chunks(8);
    let mut ret = vec![];
    for i in chunk8 {
        let s = String::from_utf8(i.to_vec())?;
        let b = binary_str_to_byte(&s)?;
        ret.push(b);
    }
    Ok(ret)
}

/// 16进制的字符串转换成byte数组。
pub fn hex_str_to_bytes(hex_str: &str) -> Result<Vec<u8>, Error> {
    Ok(hex_str.from_hex()?)
}

/// byte数组转换成16进制字符串
pub fn bytes_to_hex_str(bytes: &[u8]) -> String {
    bytes.to_hex()
}
